﻿using System;
using System.Text;
using System.Drawing;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public static partial class NativeAOT
{
    [UnmanagedCallersOnly(EntryPoint = "metcalo")]
    public static unsafe double metcalo(double z, double b, int m, double eps, IntPtr f_x_ptr)
    {
        f_x = Marshal.GetDelegateForFunctionPointer<delegatefunc_x>(f_x_ptr);

        return metcalo(z, b, m, eps);
    }

    /// <summary>
    /// 蒙特卡罗法求实根
    /// f(double x)计算方程左端函数值的函数名。
    /// </summary>
    /// <param name="z">z根的初值。</param>
    /// <param name="b">b均匀分布随机数的端点初值。</param>
    /// <param name="m">m控制调节b的参数。</param>
    /// <param name="eps">eps控制精度要求。</param>
    /// <returns>函数返回根的终值。若程序显示“b调整了100次！迭代不收敛！”，则需调整b和m的值再试。</returns>
    public static unsafe double metcalo(double z, double b, int m, double eps)
    {
        int flag, k;
        double x, z1, zz, zz1;

        k = 0;
        flag = 0;
        zz = f_x(z);
        while (flag <= 100)
        {
            k = k + 1;
            x = -b + 2.0 * b * (rnd.NextDouble());
            z1 = z + x;
            zz1 = f_x(z1);
            if (Math.Abs(zz1) >= Math.Abs(zz))
            {
                if (k == m)
                {
                    k = 0;
                    flag = flag + 1;
                    b = b / 2.0;
                }
            }
            else
            {
                k = 0;
                z = z1;
                zz = zz1;
                if (Math.Abs(zz) < eps) return (z);
            }
        }
        return (z);
    }

    /*
    // 蒙特卡罗法求实根例
      int main()
      { 
          int m;
          double b,eps;
          double z, x, mtclf(double);
          b=1.0; m=10; eps=0.00001;
          x = 0.5;
          z = metcalo(x,b,m,eps,mtclf);
          cout <<"z = " <<z <<endl;
          cout <<"检验 : f(z) = " <<mtclf(z) <<endl;
          return 0;
      }
    // 实函数方程
      double mtclf(double x)
      { 
          double  y;
          y = exp(-x*x*x) - sin(x)/cos(x) + 800.0;
          return(y);
      }
    */
}

